package com.haohan.cloud.scm.purchase.core.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haohan.cloud.scm.api.constant.NumberPrefixConstant;
import com.haohan.cloud.scm.api.constant.enums.common.TaskStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.common.UseStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.opc.SummaryStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.purchase.*;
import com.haohan.cloud.scm.api.constant.enums.supply.PdsOfferStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.supply.PdsOfferTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.supply.ShipStatusEnum;
import com.haohan.cloud.scm.api.goods.dto.GoodsModelDTO;
import com.haohan.cloud.scm.api.goods.entity.GoodsModel;
import com.haohan.cloud.scm.api.goods.feign.GoodsModelFeignService;
import com.haohan.cloud.scm.api.opc.entity.SummaryOrder;
import com.haohan.cloud.scm.api.opc.feign.OpcFeignService;
import com.haohan.cloud.scm.api.opc.feign.SummaryOrderFeignService;
import com.haohan.cloud.scm.api.opc.req.FormulaReq;
import com.haohan.cloud.scm.api.opc.req.SummaryOrderReq;
import com.haohan.cloud.scm.api.product.entity.GoodsLossRate;
import com.haohan.cloud.scm.api.product.entity.ProductInfo;
import com.haohan.cloud.scm.api.product.feign.RecipeFeignService;
import com.haohan.cloud.scm.api.product.req.RecipeReq;
import com.haohan.cloud.scm.api.product.trans.ProductInfoTrans;
import com.haohan.cloud.scm.api.purchase.dto.PurchaseTodayDTO;
import com.haohan.cloud.scm.api.purchase.entity.*;
import com.haohan.cloud.scm.api.purchase.req.*;
import com.haohan.cloud.scm.api.purchase.resp.*;
import com.haohan.cloud.scm.api.purchase.trans.*;
import com.haohan.cloud.scm.api.supply.entity.OfferOrder;
import com.haohan.cloud.scm.api.supply.entity.Supplier;
import com.haohan.cloud.scm.api.supply.feign.OfferOrderFeignService;
import com.haohan.cloud.scm.api.supply.req.AddOfferOrderReq;
import com.haohan.cloud.scm.api.supply.req.OfferOrderReq;
import com.haohan.cloud.scm.api.wms.req.EnterWarehouseByOrderDetailReq;
import com.haohan.cloud.scm.common.tools.exception.EmptyDataException;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.util.RUtil;
import com.haohan.cloud.scm.common.tools.util.ScmIncrementUtil;
import com.haohan.cloud.scm.purchase.core.IScmPurchaseOrderService;
import com.haohan.cloud.scm.purchase.service.*;
import com.haohan.cloud.scm.purchase.utils.ScmPurchaseUtils;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author cx
 * @date 2019/5/24.
 */
@Service
@AllArgsConstructor
public class ScmPurchaseOrderServiceImpl implements IScmPurchaseOrderService {
    private final PurchaseOrderService purchaseOrderService;
    private final PurchaseOrderDetailService purchaseOrderDetailService;
    private final PurchaseTaskService purchaseTaskService;
    private final OpcFeignService opcFeignService;
    private final OfferOrderFeignService offerOrderFeignService;
    private final PurchaseEmployeeService employeeService;
    private final SummaryOrderFeignService summaryOrderFeignService;
    private final RecipeFeignService recipeFeignService;
    private final GoodsModelFeignService goodsModelFeignService;
    private final ScmIncrementUtil scmIncrementUtil;
    private final PurchaseGoodsService purchaseGoodsService;
    private final PurchaseEmployeeService purchaseEmployeeService;
    private final ScmPurchaseUtils scmPurchaseUtils;

    /**
     * 新增商品采购明细
     *
     * @param summaryOrder
     * @return
     */
    @Override
    public PurchaseOrderDetail addPurchaseOrderDetailByQuery(SummaryOrder summaryOrder) {
        //获取SummaryOrder,若查询为空，返回null
        R r = opcFeignService.queryOneSummaryOrder(summaryOrder, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)|| null == r.getData()) {
            throw new EmptyDataException("找不到对应汇总单");
        }
        //在返回值中取出数据并做数据转换
        SummaryOrder order = BeanUtil.toBean(r.getData(), SummaryOrder.class);
        PurchaseOrderDetail detail = PurchaseOrderDetailTrans.summaryOrderToDetailTrans(order);
        //将转换提取出的数据插入数据库
        purchaseOrderDetailService.save(detail);
        return detail;
    }

    /**
     * 新增商品采购明细
     *
     * @param summaryOrder 汇总单实体
     * @return
     */
    @Override
    public PurchaseOrderDetail addPurchaseOrderDetail(SummaryOrder summaryOrder) {
        PurchaseOrderDetail detail = PurchaseOrderDetailTrans.summaryOrderToDetailTrans(summaryOrder);
        purchaseOrderDetailService.save(detail);
        return detail;
    }

    /**
     * 根据采购明细新增采购单
     *
     * @param req
     * @return
     */
    @Override
    public PurchaseOrder addPurchaseOrder(AddPurchaseOrderReq req) {
        PurchaseOrder order = new PurchaseOrder();
        String sn = scmIncrementUtil.inrcSnByClass(PurchaseOrder.class, NumberPrefixConstant.PURCHASE_SN_PRE);
        order.setPurchaseSn(sn);
        // 预估总价
        BigDecimal estimateAmount = BigDecimal.ZERO;
        for (String detailSn : req.getPurchaseDetailSn()) {
            QueryWrapper<PurchaseOrderDetail> query = new QueryWrapper<>();
            query.lambda()
                    .eq(PurchaseOrderDetail::getPmId,req.getPmId())
                    .eq(PurchaseOrderDetail::getPurchaseDetailSn, detailSn);
            PurchaseOrderDetail detail= purchaseOrderDetailService.getOne(query);
            if(null == detail){
                throw new EmptyDataException();
            }
            if(null != detail.getMarketPrice() && null != detail.getNeedBuyNum()){
                estimateAmount = estimateAmount.add((detail.getMarketPrice().multiply(detail.getNeedBuyNum())));
            }
            order.setReviewType(ReviewTypeEnum.no_audit);
            // 修改明细
            PurchaseOrderDetail update = new PurchaseOrderDetail();
            update.setId(detail.getId());
            update.setPurchaseSn(sn);
            purchaseOrderDetailService.updateById(update);
        }
        // 采购单初始化
        order.setPmId(req.getPmId());
        order.setPurchaseOrderType(PurchaseOrderTypeEnum.materialsNeeded);
        order.setBuyFinalTime(LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
        order.setPurchaseStatus(PurchaseStatusEnum.pending);
        order.setReviewType(ReviewTypeEnum.need_audit);
        order.setEstimateAmount(estimateAmount);
        purchaseOrderService.save(order);
        return order;
    }

    /**
     * 采购单明细 供应商确定(传入供应商/价格)
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public PurchaseOrderDetail selectOrderSupplier(ChoiceSupplierReq req) {
        //验证uId
//        scmPurchaseUtils.fetchByUid(req.getPmId(), req.getUId());
        //查询该PurchaseOrderDetail是否存在
        PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
        purchaseOrderDetail.setPmId(req.getPmId());
        purchaseOrderDetail.setId(req.getId());
        purchaseOrderDetail.setPurchaseDetailSn(req.getPurchaseDetailSn());
        PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(Wrappers.query(purchaseOrderDetail));
        if (detail == null) {
            throw new ErrorDataException();
        }
        OfferOrderReq offerOrderReq = new OfferOrderReq();
        offerOrderReq.setOfferOrderId(req.getOfferOrderId());
        offerOrderReq.setOfferType(PurchaseEnumTrans.change(detail.getMethodType()));
        // 关联报价单
        R r = offerOrderFeignService.getOneByOfferOrderReq(offerOrderReq,SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || null == r.getData()) {
            throw new ErrorDataException();
        }
        OfferOrder offerOrder = BeanUtil.toBean(r.getData(), OfferOrder.class);
        //设置报价单更新字段
        OfferOrder order = new OfferOrder();
        order.setId(offerOrder.getId());
        order.setPurchaseDetailSn(req.getPurchaseDetailSn());
        //报价单状态修改: 中标;  发货状态修改: 待备货;
        order.setStatus(PdsOfferStatusEnum.bidding);
        order.setShipStatus(ShipStatusEnum.startCargo);
        offerOrderFeignService.updateById(order, SecurityConstants.FROM_IN);

        PurchaseOrderDetail updateDetail = PurchaseOrderSupplierTrans.purchaseOrderSupplierTrans(offerOrder);
        updateDetail.setId(detail.getId());
        // 供应商选定时为 已中标
        purchaseOrderDetailService.updateById(updateDetail);
        return detail;
    }

    /**
     * 查询采购任务列表(带采购商品信息)
     *
     * @param req
     * @return
     */
    @Override
    public Page queryPurchaseTaskList(PurchasePageReq req) {
//        scmPurchaseUtils.fetchByUid(req.getPmId(), req.getUid());
        //设置分页查询参数
        Page page = new Page(req.getCurrent(), req.getSize());
        PurchaseTask purchaseTask = new PurchaseTask();
        BeanUtil.copyProperties(req,purchaseTask);
        IPage iPage = purchaseTaskService.page(page, Wrappers.query(purchaseTask));
        //根据任务列表查询商品信息
        List<PurchaseTask> taskList = (List<PurchaseTask>)iPage.getRecords();
        List<PurchaseTaskListResp> list = new ArrayList<>();
        for (PurchaseTask task : taskList) {
            QueryWrapper<PurchaseOrderDetail> query = new QueryWrapper<>();
            query.lambda()
                    .eq(PurchaseOrderDetail::getPmId, req.getPmId())
                    .eq(PurchaseOrderDetail::getPurchaseDetailSn, task.getPurchaseDetailSn());
            PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(query);
            if (null == detail) {
                // 未关联采购明细的任务忽略
                continue;
            }
            PurchaseTaskListResp purchaseTaskListReq = PurchaseTaskListTrans.getPurchaseTaskListReq(task, detail);
            list.add(purchaseTaskListReq);
        }
        //设置返回参数
        page.setRecords(list);
        return page;
    }

    /**
     * 分页查询 员工任务
     * @param req
     * @return
     */
    private Page queryTaskPage(PurchasePageReq req){
        Page queryPage = new Page();
        queryPage.setCurrent(req.getCurrent());
        queryPage.setSize(req.getSize());
        PurchaseTask queryTask = new PurchaseTask();
        queryTask.setPmId(req.getPmId());
        queryTask.setTaskStatus(req.getTaskStatus());
//        queryTask.setTransactorId(req.getUid());
        //查询分页内容
        Page page = (Page)purchaseTaskService.page(queryPage, Wrappers.query(queryTask));
        if (CollUtil.isEmpty(page.getRecords())) {
            throw new EmptyDataException();
        }
        return page;
    }

    /**
     * 查询当前任务列表(带采购商品信息) 采购总监
     *
     * @param req
     * @return
     */
    @Override
    public Page<PurchaseTaskListByDirectorResp> queryTaskListByDirector(PurchasePageReq req) {
        PurchaseEmployee employee = scmPurchaseUtils.fetchByUid(req.getPmId(), req.getUid());
        if(employee.getPurchaseEmployeeType() != EmployeeTypeEnum.director) {
            throw new ErrorDataException("必需是采购总监");
        }
        // 总监任务列表
        Page page = queryTaskPage(req);
        //根据任务列表查询商品信息
        List<PurchaseTask> taskList = (List<PurchaseTask>)page.getRecords();
        List<PurchaseTaskListByDirectorResp> list = new ArrayList<>();
        PurchaseTaskListByDirectorResp resp;
        for (PurchaseTask task : taskList) {
            QueryWrapper<PurchaseOrderDetail> query = new QueryWrapper<>();
            query.lambda()
                    .eq(PurchaseOrderDetail::getPmId, req.getPmId())
                    .eq(PurchaseOrderDetail::getPurchaseSn, task.getPurchaseSn());
            // 采购明细列表
            List<PurchaseOrderDetail> detailList = purchaseOrderDetailService.list(query);
            if (CollUtil.isEmpty(detailList)) {
                // 无采购明细的任务忽略
                continue;
            }
            resp = new PurchaseTaskListByDirectorResp();
            resp.setDeadlineTime(task.getDeadlineTime());
            resp.setTaskStatus(task.getTaskStatus());
            resp.setDetailList(detailList);
            list.add(resp);
        }
        // 返回参数
        page.setRecords(list);
        return page;
    }

    /**
     * 查询采购任务详情(带采购商品信息)
     *
     * @param req
     * @return
     */
    @Override
    public PurchaseTaskDetailResp queryPurchaseTask(QueryPurchaseTaskReq req) {
        PurchaseTask task = purchaseTaskService.getById(req.getId());
        if (null == task) {
            throw new EmptyDataException();
        }
        QueryWrapper<PurchaseOrderDetail> detailQueryWrapper = new QueryWrapper<>();
        detailQueryWrapper.lambda()
          .eq(PurchaseOrderDetail::getPmId,task.getPmId())
          .eq(PurchaseOrderDetail::getPurchaseDetailSn,task.getPurchaseDetailSn());
        PurchaseOrderDetail one = purchaseOrderDetailService.getOne(detailQueryWrapper);
        if(null == one){
          throw new EmptyDataException();
        }
      PurchaseTaskDetailResp resp = PurchaseTaskDetailTrans.getDetail(task, one);
      return resp;
    }

    /**
     * 总监 执行采购任务(审核) 批量通过
     *
     * @param req 采购任务id、执行人id、执行人备注、任务执行方式为审核
     * @return
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    @ApiOperation(value = "采购任务审核——小程序" ,notes = "总监 执行采购任务(审核) 批量通过")
    public Boolean auditTaskBatch(AuditTaskBatchReq req) {
        PurchaseEmployee purchaseEmployee = scmPurchaseUtils.fetchByUid(req.getPmId(), req.getUId());
        //查询采购任务
        PurchaseTask queryTask = new PurchaseTask();
        queryTask.setId(req.getId());
        queryTask.setPmId(req.getPmId());
        queryTask.setTaskActionType(TaskActionTypeEnum.audit);
        PurchaseTask task = purchaseTaskService.getOne(Wrappers.query(queryTask));
        if(null == task) {
          throw new EmptyDataException();
        }
        task.setTaskStatus(TaskStatusEnum.finish);
        //查询采购单对应的采购明细
        PurchaseOrderDetail  queryDetail = new PurchaseOrderDetail();
        queryDetail.setPurchaseSn(task.getPurchaseSn());
        List<PurchaseOrderDetail> detailList = purchaseOrderDetailService.list(Wrappers.query(queryDetail));
        if(CollUtil.isEmpty(detailList)){
          throw new EmptyDataException();
        }
        //查询采购明细对应商品的负责人通行证Id
        for(PurchaseOrderDetail detail : detailList){
            //查询商品信息
            PurchaseGoods queryGoods = new PurchaseGoods();
            queryGoods.setPmId(req.getPmId());
            queryGoods.setGoodsId(detail.getGoodsId());
            PurchaseGoods good = purchaseGoodsService.getOne(Wrappers.query(queryGoods),false);
            if(null == good){
                throw new EmptyDataException();
          }
          //查询商品信息对应的负责人通行证Id
          PurchaseEmployee employee = purchaseEmployeeService.getById(good.getEmployeeId());
          if(null == employee){
            throw new EmptyDataException();
          }
          //创建采购任务，分配给具体执行人
          PurchaseTask newTask = new PurchaseTask();
          newTask.setPmId(req.getPmId());
          newTask.setTaskStatus(TaskStatusEnum.finish);
          newTask.setInitiatorId(purchaseEmployee.getUserId());
          newTask.setInitiatorName(purchaseEmployee.getName());
          newTask.setTransactorId(employee.getPassportId());
          newTask.setTransactorName(employee.getName());
          if(StrUtil.isEmpty(req.getActionDesc())){
            newTask.setActionDesc(req.getActionDesc());
          }
          newTask.setPurchaseDetailSn(detail.getPurchaseDetailSn());
          newTask.setPurchaseSn(task.getPurchaseSn());
          newTask.setTaskActionType(TaskActionTypeEnum.procurement);
          newTask.setDeadlineTime(detail.getBuyFinalTime());
          //保存分配后的采购任务
          if(!purchaseTaskService.save(newTask)){
            throw new ErrorDataException();
          }
        }
        //更新总监采购任务状态
        if(!purchaseTaskService.updateById(task)){
          throw new ErrorDataException();
        }
      return true;
    }

    /**
     * 总监 执行采购任务(审核) 修改采购单明细
     *
     * @param req 采购任务id、关闭 或 修改采购方式/数量
     * @return
     */
    @Override
    public PurchaseOrderDetail auditTask(AuditTaskReq req) {
        PurchaseTask purchaseTask = purchaseTaskService.getById(req.getId());
        if (purchaseTask==null){
            throw new ErrorDataException();
        }
        //关联采购单明细 (关闭 或 修改采购方式/数量)
        PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
        purchaseOrderDetail.setPurchaseDetailSn(purchaseTask.getPurchaseDetailSn());
        PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(Wrappers.query(purchaseOrderDetail));
        if (detail==null){
            throw new ErrorDataException("detail为空");
        }
        if (req.getPurchaseStatus()!=null && PurchaseStatusEnum.getByType(req.getPurchaseStatus())==PurchaseStatusEnum.close){
            //关闭采购单
            detail.setPurchaseStatus(PurchaseStatusEnum.getByType(req.getPurchaseStatus()));
        }else {
            //修改采购方式/数量
            detail.setMethodType(MethodTypeEnum.getByType(req.getMethodType()));
          detail.setNeedBuyNum(req.getNeedBuyNum());
        }
        purchaseOrderDetailService.updateById(detail);

        return detail;
    }

    /**
     * 经理 执行采购任务(分配) 指定采购员
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean appointTask(AppointTaskReq req) {
        //查询条件：采购任务id、任务执行方式为分配
        PurchaseTask taskReq = new PurchaseTask();
        taskReq.setPmId(req.getPmId());
        taskReq.setId(req.getId());
        taskReq.setTaskActionType(TaskActionTypeEnum.allocation);
        PurchaseTask purchaseTask = purchaseTaskService.getOne(Wrappers.query(taskReq));
        if (null==purchaseTask){
            throw new EmptyDataException("无可执行的采购分配任务");
        }
        //关联采购员工 获取员工姓名
        PurchaseEmployee purchaseEmployee = new PurchaseEmployee();
        purchaseEmployee.setId(req.getEmployeeId());
        purchaseEmployee.setPurchaseEmployeeType(EmployeeTypeEnum.buyer);
        PurchaseEmployee employee = employeeService.getOne(Wrappers.query(purchaseEmployee));
        if (null==employee){
            throw new EmptyDataException("查询采购员工有误");
        }

        // 重新指派采购员
        String taskId = "";
        if(purchaseTask.getTaskStatus() == TaskStatusEnum.finish){
            // 查询原 采购员 任务
            QueryWrapper<PurchaseTask> queryTask = new QueryWrapper<>();
            queryTask.lambda()
                    .eq(PurchaseTask::getPmId, req.getPmId())
                    .eq(PurchaseTask::getTaskActionType, TaskActionTypeEnum.procurement)
                    .eq(PurchaseTask::getPurchaseDetailSn, purchaseTask.getPurchaseDetailSn());
            PurchaseTask existTask = purchaseTaskService.getOne(queryTask);
            if(null != existTask){
                taskId = existTask.getId();
            }
        }
        // 创建采购任务(采购)
        PurchaseTask newTask = PurchaseTaskDetailTrans.purchaseTaskTrans(purchaseTask, employee);
        //任务内容说明
        newTask.setContent(req.getContent());
        //任务截止时间
        LocalDateTime deadLineTime = req.getDeadlineTime();
        if(null != deadLineTime){
            newTask.setDeadlineTime(deadLineTime);
        }
        if(StrUtil.isEmpty(taskId)){
            purchaseTaskService.save(newTask);
        }else{
            newTask.setId(taskId);
            purchaseTaskService.updateById(newTask);
        }
        // 完成采购分配任务
        PurchaseTask task = new PurchaseTask();
        task.setId(purchaseTask.getId());
        task.setActionDesc(req.getActionDesc());
        task.setTaskStatus(TaskStatusEnum.finish);
        task.setActionTime(LocalDateTime.now());
        purchaseTaskService.updateById(task);
        return true;

    }

    /**
     * 库存不满足时  运营 发起需求采购 设置项(损耗率/协议供应)查询
     * @param req
     * @return
     */
    @Override
    public List<GoodsLossRate> queryGoodsLossList(QueryGoodsLossReq req) {
        List<GoodsLossRate> list = new ArrayList<>();
        // 入参:汇总单编号
        // 调配类型1.采购
        SummaryOrderReq request = new SummaryOrderReq();
        request.setSummaryOrderId(req.getSummaryOrderId());
        R result = summaryOrderFeignService.getOneBySummaryOrderReq(request, SecurityConstants.FROM_IN);
        if(RUtil.isSuccess(result)==false){
          throw new EmptyDataException("查询为空");
        }
        SummaryOrder order = BeanUtil.toBean(result.getData(), SummaryOrder.class);
        // 判断商品是否需组合 (查询配方表)
        if(this.isGoodsRecipe(order)==false){

      }

      //  查询对应单品的损耗率 (组合的为多个对应的原材料的损耗率)

      // 判断是否协议供应商品 (查询协议供应商品表)
      //  对应协议供应商

      // 返回: 商品对应损耗率列表
      return list;
    }
    /**
     * 判断商品是否需要组合
     * @param order
     * @return
     */
    @Override
    public Boolean isGoodsRecipe(SummaryOrder order){
        RecipeReq req = new RecipeReq();
        req.setGoodsModelId(order.getGoodsModelId());
        R result = recipeFeignService.getOneByRecipeReq(req, SecurityConstants.FROM_IN);
        if(RUtil.isSuccess(result)==false){
          return false;
        }
        return true;
    }
    /**
     *  采购部 发起需求采购
     * @param req
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public List<PurchaseOrderDetail> initiateDemandPurchase(PurchaseNeedReq req) {
        List<PurchaseOrderDetail> list = new ArrayList<>();
        //根据明细编号查询返回detail明细
        QueryWrapper<PurchaseOrderDetail> query = new QueryWrapper<>();
        query.lambda()
          .eq(PurchaseOrderDetail::getPmId,req.getPmId())
          .eq(PurchaseOrderDetail::getPurchaseDetailSn,req.getOriginalPurchaseDetailSn());
        PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(query);
        if(null==detail){
          throw new ErrorDataException("数据为空");
        }
        for(FormulaReq fReq:req.getPurchaseInfo()){
          R result = goodsModelFeignService.getInfoById(fReq.getGoodsModelId(), SecurityConstants.FROM_IN);
          GoodsModel model = BeanUtil.toBean(result.getData(),GoodsModel.class);
          PurchaseOrderDetail orderDetail = new PurchaseOrderDetail();
          BeanUtil.copyProperties(model,detail);
          BeanUtil.copyProperties(detail,orderDetail);
          orderDetail.setOriginalPurchaseDetailSn(req.getOriginalPurchaseDetailSn());
          orderDetail.setPurchaseOrderType(PurchaseOrderTypeEnum.materialsNeeded);
          if (req.getMethodType().equals(MethodTypeEnum.single.getType())) {
            orderDetail.setSupplierId(req.getSupplierId());
            orderDetail.setBuyPrice(req.getBuyPrice());
          } else if (req.getMethodType().equals(MethodTypeEnum.bidding.getType())) {
            orderDetail.setBiddingEndTime(req.getBiddingEndTime());
          } else if (req.getMethodType().equals(MethodTypeEnum.agreement.getType())) {
            orderDetail.setSupplierId(req.getSupplierId());
          }
          list.add(orderDetail);
          if (purchaseOrderDetailService.save(orderDetail)){
            throw new ErrorDataException("采购明细保存失败");
          }
        }
        return list;
    }

    /**
     *  采购部/高管/运营  发起采购计划(经理/采购员)
     * @param req
     * @return
     */
    @Override
    public PurchaseOrderDetail initiatePurchasePlan(InitiatePurchasePlanReq req) {
        //查询商品信息
        GoodsModelDTO goodsInfo = scmPurchaseUtils.fetchGoodsModel(req.getGoodsModelId());
        //将goodsInfo中的数据填入PurchaseOrderDetail
        PurchaseOrderDetail detail = PurchaseInitPlanTrans.initDetail(goodsInfo);
        detail.setPmId(req.getPmId());
        detail.setNeedBuyNum(req.getNeedBuyNum());
        detail.setGoodsModelId(req.getGoodsModelId());
        //判断采购方式类型填入数据
        if(req.getMethodType() == MethodTypeEnum.agreement.getType()){
          detail.setSupplierId(req.getSupplierId());
        }else if(req.getMethodType() == MethodTypeEnum.bidding.getType()){
          detail.setBiddingEndTime(req.getBiddingEndTime());
        }else if(req.getMethodType() == MethodTypeEnum.single.getType()){
          detail.setSupplierId(req.getSupplierId());
          detail.setBuyPrice(req.getBuyPrice());
        }
        if(!purchaseOrderDetailService.save(detail)){
          throw new ErrorDataException("生成采购明细失败");
        }
        return detail;
    }

    /**
     * 采购单明细 供应商确定(传入供应商/价格)
     * 小程序：单品采购
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PurchaseOrderDetail singlePurchase(SinglePurchaseReq req){
        String pmId = req.getPmId();
        //验证
//        scmPurchaseUtils.fetchByUid(req.getPmId(),req.getUId());
        //检查采购任务 不为已完成
        QueryWrapper<PurchaseTask> query = new QueryWrapper<>();
        query.lambda()
                .eq(PurchaseTask::getPmId, pmId)
                .eq(PurchaseTask::getId, req.getTaskId())
                .ne(PurchaseTask::getTaskStatus, TaskStatusEnum.finish);
        PurchaseTask task = purchaseTaskService.getOne(query);
        if(null == task){
            throw new ErrorDataException("采购任务有误");
        }
        //检查采购明细  采购中
        QueryWrapper<PurchaseOrderDetail> queryDetail = new QueryWrapper<>();
        queryDetail.lambda()
                .eq(PurchaseOrderDetail::getPmId, pmId)
                .eq(PurchaseOrderDetail::getPurchaseDetailSn, req.getPurchaseDetailSn())
                .eq(PurchaseOrderDetail::getPurchaseStatus, PurchaseStatusEnum.purchasing);
        PurchaseOrderDetail purchaseDetail = purchaseOrderDetailService.getOne(queryDetail);
        if(null == purchaseDetail){
            throw new ErrorDataException("采购明细有误");
        }
        // 供应商
        Supplier supplier = scmPurchaseUtils.fetchSupplier(req.getSupplierId());
        if(null == supplier){
            throw new ErrorDataException("供应商有误");
        }
        //填充采购明细字段 设为 中标 / 备货中
        purchaseDetail.setMethodType(MethodTypeEnum.single);
        purchaseDetail.setBuyPrice(req.getRealBuyPrice());
        purchaseDetail.setSupplierId(req.getSupplierId());
        purchaseDetail.setSupplierName(supplier.getSupplierName());
        purchaseDetail.setPayType(PayTypeEnum.getByType(req.getPayType()));
        purchaseDetail.setBiddingStatus(BiddingStatusEnum.alreadyBidding);
        purchaseDetail.setReceiveType(ReceiveTypeEnum.delivery);
        purchaseDetail.setPurchaseStatus(PurchaseStatusEnum.stockUp);
        // 创建报价单 并设置为中标 / 待备货
        AddOfferOrderReq offerReq = PurchaseOfferTrans.offerTrans(purchaseDetail);
        offerReq.setSupplierId(supplier.getId());
        offerReq.setStatus(PdsOfferStatusEnum.bidding.getType());
        offerReq.setShipStatus(ShipStatusEnum.stayCargo.getType());
        offerReq.setPrepareDate(purchaseDetail.getBuyFinalTime().toLocalDate());
        offerReq.setDealPrice(req.getRealBuyPrice());
        scmPurchaseUtils.addOfferOrder(offerReq);
        // 更新采购单明细
        if(!purchaseOrderDetailService.updateById(purchaseDetail)){
            throw new ErrorDataException("更新采购单明细失败");
        }
        // todo 检查修改采购单状态
        //修改任务状态 执行中
        PurchaseTask purchaseTask = new PurchaseTask();
        if (task.getTaskActionType()==TaskActionTypeEnum.allocation){
            //经理执行采购
            purchaseTask.setTaskActionType(TaskActionTypeEnum.procurement);
        }
        purchaseTask.setId(task.getId());
        purchaseTask.setTaskStatus(TaskStatusEnum.doing);
        purchaseTask.setActionTime(LocalDateTime.now());
        purchaseTaskService.updateById(purchaseTask);
        return purchaseDetail;
    }
    /**
     * 采购单明细 供应商确定(传入供应商/价格)
     * 小程序：协议供应
     * @param req
     * @return
     */
    @Override
    public PurchaseOrderDetail agreementPurchase(AgreementPurchaseReq req) {
        //验证用户登录信息
        scmPurchaseUtils.fetchByUid(req.getPmId(),req.getUId());
        //查询此采购明细是否存在
        PurchaseOrderDetail detail = new PurchaseOrderDetail();
        detail.setPmId(req.getPmId());
        detail.setId((req.getId()));
        PurchaseOrderDetail pod = purchaseOrderDetailService.getOne(Wrappers.query(detail));
        if(null == pod){
          throw new EmptyDataException();
        }
        //若存在修改采购价格
        pod.setMethodType(MethodTypeEnum.agreement);
        if(req.getBuyPrice() != null) {
          pod.setBuyPrice(req.getBuyPrice());
        }
        //更新采购单明细
        if(!purchaseOrderDetailService.updateById(pod)){
          throw new ErrorDataException();
        }
        //查询与采购单明细编号对应的报价单
        OfferOrderReq oor = new OfferOrderReq();
        oor.setPurchaseDetailSn(pod.getPurchaseDetailSn());
        oor.setOfferType(PdsOfferTypeEnum.appointOffer);
        oor.setStatus(PdsOfferStatusEnum.bidding);
        R roor = offerOrderFeignService.getOneByOfferOrderReq(oor, SecurityConstants.FROM_IN);
        if(!RUtil.isSuccess(roor) || null == roor.getData()){
          throw new EmptyDataException();
        }
        //更新报价单成交价格
        OfferOrder offerOrder = BeanUtil.toBean(roor.getData(), OfferOrder.class);
        offerOrder.setDealPrice(req.getBuyPrice());
        R r = offerOrderFeignService.updateById(offerOrder, SecurityConstants.FROM_IN);
        if(!RUtil.isSuccess(r)){
          throw new ErrorDataException();
        }
        //调用确认采购商方法并返回
        ChoiceSupplierReq choiceReq = new ChoiceSupplierReq();
        choiceReq.setId(pod.getId());
        choiceReq.setPmId(pod.getPmId());
        choiceReq.setOfferOrderId(pod.getPurchaseDetailSn());
        choiceReq.setPurchaseDetailSn(detail.getPurchaseDetailSn());
        choiceReq.setOfferOrderId(offerOrder.getOfferOrderId());
        return this.selectOrderSupplier(choiceReq);
    }

    /**
     * 新增采购单(采购单明细)/初始化采购任务/创建货品信息/初始化入库单/初始化入库单明细
     *   用于 直接 新增采购计划/按需采购
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addPurchaseOrderAndDetail(AddPurchaseOrderAndDetailReq req) {
        //生成采购单编号
        String sn = scmIncrementUtil.inrcSnByClass(PurchaseOrder.class, NumberPrefixConstant.PURCHASE_SN_PRE);
        String pmId = req.getPmId();
        //创建采购单
        PurchaseOrder order = new PurchaseOrder();
        order.setPmId(pmId);
        order.setPurchaseSn(sn);
        order.setPurchaseOrderType(req.getPurchaseOrderType());
        order.setBuyFinalTime(req.getBuyFinalTime());
        order.setReviewType(req.getReviewType());
        //TODO 发起人
        String initiatorId = "";
        String initiatorName = "";
        // 审核状态
        boolean flag = req.getReviewType()==ReviewTypeEnum.need_audit;
        PurchaseStatusEnum status = (flag ? PurchaseStatusEnum.checking : PurchaseStatusEnum.purchasing);
        order.setPurchaseStatus(status);
        PurchaseTask managerTask;
        if (flag){
            managerTask = initTask(req.getTransactorId(), order, initiatorId, initiatorName);
        }else{
            // 不审核的操作  采购明细 自动分配采购经理
            managerTask = initManagerTask(order, initiatorId, initiatorName);
        }
        //预估总价
        BigDecimal estimateAmount = BigDecimal.ZERO;
        for (ParamsReq paramsReq : req.getList()) {
            String purchaseOrderDetailSn = scmIncrementUtil.inrcSnByClass(PurchaseOrderDetail.class, NumberPrefixConstant.PURCHASE_DETAIL_SN_PRE);
            GoodsModelDTO goodsModelDTO = scmPurchaseUtils.fetchGoodsModel(paramsReq.getGoodsModelId());
            //创建采购单明细
            PurchaseOrderDetail orderDetail = PurchaseOrderDetailTrans.trans(goodsModelDTO,paramsReq);
            orderDetail.setPurchaseSn(sn);
            orderDetail.setPurchaseDetailSn(purchaseOrderDetailSn);
            orderDetail.setNeedBuyNum(paramsReq.getNeedBuyNum());
            orderDetail.setSummaryDetailSn(paramsReq.getSummaryOrderId());
            orderDetail.setPmId(pmId);
            orderDetail.setPurchaseStatus(status);
            purchaseOrderDetailService.save(orderDetail);
            // 不审核的操作  采购明细 自动分配采购经理
            if(!flag){
                managerTask.setPurchaseDetailSn(purchaseOrderDetailSn);
                managerTask.setId(null);
                managerTask.setTenantId(null);
                purchaseTaskService.save(managerTask);
            }
            //计算预估总价
            estimateAmount = estimateAmount.add(orderDetail.getMarketPrice().multiply(orderDetail.getNeedBuyNum()));
            //创建货品信息
            ProductInfo info = ProductInfoTrans.trans(orderDetail);
            scmPurchaseUtils.createProductInfo(info);
        }
        order.setEstimateAmount(estimateAmount);
        purchaseOrderService.save(order);
        //初始化入库单
        EnterWarehouseByOrderDetailReq enterWarehouseByOrderDetailReq = new EnterWarehouseByOrderDetailReq();
        enterWarehouseByOrderDetailReq.setPmId(pmId);
        enterWarehouseByOrderDetailReq.setPurchaseSn(sn);
        scmPurchaseUtils.addEnterWarehouse(enterWarehouseByOrderDetailReq);
        return true;
    }

    /**
     * 初始设置 经理任务
     *   未设置 purchaseDetailSn
     * @param order
     * @param initiatorId
     * @param initiatorName
     * @return
     */
    private PurchaseTask initManagerTask(PurchaseOrder order, String initiatorId, String initiatorName) {
        // 默认经理
        QueryWrapper<PurchaseEmployee> query = new QueryWrapper<>();
        query.lambda()
                .eq(PurchaseEmployee::getPmId, order.getPmId())
                .eq(PurchaseEmployee::getUseStatus, UseStatusEnum.enabled)
                .eq(PurchaseEmployee::getPurchaseEmployeeType, EmployeeTypeEnum.manager);
        PurchaseEmployee purchaseEmployee = purchaseEmployeeService.getOne(query, false);
        if(null == purchaseEmployee){
            throw new ErrorDataException("无可选择采购经理");
        }
        PurchaseTask task = PurchaseInfoTrans.addPurchaseTask(order);
        task.setTaskActionType(TaskActionTypeEnum.allocation);
        task.setInitiatorId(initiatorId);
        task.setInitiatorName(initiatorName);
        task.setTransactorId(purchaseEmployee.getId());
        task.setTransactorName(purchaseEmployee.getName());
        return task;
    }

    /**
     * 设置采购任务 (总监 审核任务) 并保存
     * @param transactorId
     * @param order
     * @param initiatorId
     * @param initiatorName
     */
    private PurchaseTask initTask(String transactorId, PurchaseOrder order, String initiatorId, String initiatorName) {
        // 审核任务执行人(采购总监)设置
        PurchaseEmployee purchaseEmployee = purchaseEmployeeService.getById(transactorId);
        if(null == purchaseEmployee || purchaseEmployee.getPurchaseEmployeeType() != EmployeeTypeEnum.director
                || purchaseEmployee.getUseStatus() != UseStatusEnum.enabled){
            throw new ErrorDataException("采购单审核人有误");
        }
        PurchaseTask task = PurchaseInfoTrans.addPurchaseTask(order);
        task.setInitiatorId(initiatorId);
        task.setInitiatorName(initiatorName);
        task.setTransactorId(purchaseEmployee.getId());
        task.setTransactorName(purchaseEmployee.getName());
        purchaseTaskService.save(task);
        return task;
    }

    /**
     * 发起采购  修改 采购单状态为 <待审核>, 同时新增 入库单/任务/货品
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean beginPurchase(BeginPurchaseReq req){
        String pmId = req.getPmId();
        String sn = req.getPurchaseSn();
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<>();
        // 状态需为 待处理
        queryWrapper.lambda()
                .eq(PurchaseOrder::getPmId, pmId)
                .eq(PurchaseOrder::getPurchaseStatus, PurchaseStatusEnum.pending)
                .eq(PurchaseOrder::getPurchaseSn, sn);
        PurchaseOrder purchaseOrder = purchaseOrderService.getOne(queryWrapper);
        if(null == purchaseOrder){
            throw new ErrorDataException("采购单有误");
        }
        //TODO 发起人
        String initiatorId = "";
        String initiatorName = "";
        // 修改采购单
        PurchaseOrder update = new PurchaseOrder();
        update.setId(purchaseOrder.getId());
        update.setPurchaseOrderType(req.getPurchaseOrderType());
        update.setBuyFinalTime(req.getBuyFinalTime());
        update.setReviewType(req.getReviewType());
        // 新增审核任务
        // 审核状态
        boolean flag = req.getReviewType()==ReviewTypeEnum.need_audit;
        PurchaseTask managerTask;
        if (flag){
            managerTask = initTask(req.getTransactorId(), purchaseOrder, initiatorId, initiatorName);
        }else{
            // 不审核的操作  采购明细 自动分配采购经理
            managerTask = initManagerTask(purchaseOrder, initiatorId, initiatorName);
        }
        PurchaseStatusEnum status = (flag ? PurchaseStatusEnum.checking : PurchaseStatusEnum.purchasing);
        update.setPurchaseStatus(status);

        QueryWrapper<PurchaseOrderDetail> queryDetail = new QueryWrapper<>();
        queryDetail.lambda()
                .eq(PurchaseOrderDetail::getPmId, pmId)
                .eq(PurchaseOrderDetail::getPurchaseSn, sn);
        List<PurchaseOrderDetail> detailList = purchaseOrderDetailService.list(queryDetail);
        if(CollUtil.isEmpty(detailList)){
            throw new ErrorDataException("采购单明细有误");
        }

        for(PurchaseOrderDetail detail:detailList){
            PurchaseOrderDetail updateDetail = new PurchaseOrderDetail();
            updateDetail.setId(detail.getId());
            updateDetail.setPurchaseStatus(status);
            purchaseOrderDetailService.updateById(updateDetail);
            // 不审核的操作  采购明细 自动分配采购经理
            if(!flag){
                managerTask.setPurchaseDetailSn(detail.getPurchaseDetailSn());
                managerTask.setId(null);
                managerTask.setTenantId(null);
                purchaseTaskService.save(managerTask);
            }
            //创建货品信息
            ProductInfo info = ProductInfoTrans.trans(detail);
            scmPurchaseUtils.createProductInfo(info);
        }
        //初始化入库单
        EnterWarehouseByOrderDetailReq enterWarehouseByOrderDetailReq = new EnterWarehouseByOrderDetailReq();
        enterWarehouseByOrderDetailReq.setPmId(pmId);
        enterWarehouseByOrderDetailReq.setPurchaseSn(sn);
        scmPurchaseUtils.addEnterWarehouse(enterWarehouseByOrderDetailReq);

        purchaseOrderService.updateById(update);
        return true;
    }

    /**
     * 查询今日采购总额
     * @return
     */
    @Override
    public BigDecimal queryTodayAmount(PurchaseTodayDTO dto) {
        if(StrUtil.isEmpty(dto.getStart())){
            dto.setStart(scmPurchaseUtils.todayStart());
        }
        if(StrUtil.isEmpty(dto.getEnd())){
            dto.setEnd(scmPurchaseUtils.todayEnd());
        }
        BigDecimal bigDecimal = purchaseOrderService.queryTodayAmount(dto);
        return bigDecimal;
    }

    /**
     * 查询采购状态数量
     * @return
     */
    @Override
    public List<Map<String, Object>> queryPurchaseStatus(String pmId) {
        List<Map<String,Object>> list = new ArrayList<>();
        //未采购
        Map<String,Object> wmap = new HashMap<>();
        QueryWrapper<PurchaseOrder> query  = new QueryWrapper<>();
        query.lambda()
                .eq(PurchaseOrder::getPmId,pmId)
                .eq(PurchaseOrder::getPurchaseStatus,PurchaseStatusEnum.pending);
        int wait = purchaseOrderService.count(query);
        wmap.put("name","待采购");
        wmap.put("value",wait);
        list.add(wmap);
        //采购中
        Map<String,Object> pmap = new HashMap<>();
        QueryWrapper<PurchaseOrder> query1  = new QueryWrapper<>();
        query1.lambda()
                .eq(PurchaseOrder::getPmId,pmId)
                .eq(PurchaseOrder::getPurchaseStatus,PurchaseStatusEnum.purchasing);
        int purchase = purchaseOrderService.count(query1);
        pmap.put("name","已完成");
        pmap.put("value",purchase);
        list.add(pmap);
        //采购完成
        Map<String,Object> fmap = new HashMap<>();
        QueryWrapper<PurchaseOrder> query2  = new QueryWrapper<>();
        query2.lambda()
                .eq(PurchaseOrder::getPmId,pmId)
                .eq(PurchaseOrder::getPurchaseStatus,PurchaseStatusEnum.finish);
        int finish = purchaseOrderService.count(query2);
        fmap.put("name","已完成");
        fmap.put("value",finish);
        list.add(fmap);
        return list;
    }

    /**
     * 编辑采购单详情
     *   用于 采购单状态 在<待处理> 时
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean editPurchaseOrder(EditPurchaseOrderReq req) {
        //更新采购单
        PurchaseOrder queryOrder = new PurchaseOrder();
        queryOrder.setPmId(req.getPmId());
        queryOrder.setPurchaseSn(req.getPurchaseSn());
        PurchaseOrder order = purchaseOrderService.getOne(Wrappers.query(queryOrder));
        if(order == null){
            throw new ErrorDataException("采购单不存在");
        }
        if(order.getPurchaseStatus() != PurchaseStatusEnum.pending){
            throw new ErrorDataException("采购单当前状态不可修改");
        }
        PurchaseOrder updOrder = new PurchaseOrder();
        BeanUtil.copyProperties(req,updOrder);
        updOrder.setId(order.getId());
        if(!purchaseOrderService.updateById(updOrder)){
            throw new ErrorDataException("采购单更新失败");
        }
        //更新采购详情
        for(PurchaseOrderDetail detail:req.getDetailList()){
            PurchaseOrderDetail det = purchaseOrderDetailService.getById(detail.getId());
            if( det == null){
                throw new EmptyDataException("采购详情为空");
            }
            PurchaseOrderDetail updDetail = new PurchaseOrderDetail();
            BeanUtil.copyProperties(detail,updDetail);
            if(StrUtil.isNotBlank(req.getMethodType())){
                updDetail.setMethodType(MethodTypeEnum.getByType(req.getMethodType()));
            }
            if(!purchaseOrderDetailService.updateById(updDetail))  {
                throw new ErrorDataException("更新采购详情失败");
            }
        }
        if(!req.getDelDetails().isEmpty()){
            req.getDelDetails().forEach(detail -> {
                PurchaseOrderDetail orderDetail = purchaseOrderDetailService.getById(detail.getId());
                // 若有汇总单 处理成功时 删除采购明细
                if (null != orderDetail && modifySummaryOrder(orderDetail)) {
                    purchaseOrderDetailService.removeById(detail.getId());
                }
            });
        }
        if(!req.getAddDetails().isEmpty()){
            req.getAddDetails().forEach(detail -> {
                detail.setPurchaseSn(order.getPurchaseSn());
                detail.setPmId(order.getPmId());
                detail.setPurchaseStatus(order.getPurchaseStatus());
                detail.setPurchaseOrderType(PurchaseOrderTypeEnum.purchasePlan);
                detail.setMethodType(MethodTypeEnum.single);
                if(!purchaseOrderDetailService.save(detail)){
                    throw new ErrorDataException("新增采购明细失败");
                }
            });
        }
        return true;
    }

    /**
     *  若有汇总单 修改为 待处理状态
     *    更新失败时返回 false
     * @param orderDetail
     * @return
     */
    private Boolean modifySummaryOrder(PurchaseOrderDetail orderDetail) {
        String summarySn = orderDetail.getSummaryDetailSn();
        if (StrUtil.isEmpty(summarySn)) {
            return true;
        }
        SummaryOrderReq req = new SummaryOrderReq();
        req.setPmId(orderDetail.getPmId());
        req.setSummaryOrderId(summarySn);
        SummaryOrder summaryOrder = scmPurchaseUtils.fetchSummaryOrder(req);
        if(null == summaryOrder){
            return true;
        }
        SummaryOrder update = new SummaryOrder();
        update.setId(summaryOrder.getId());
        update.setSummaryStatus(SummaryStatusEnum.wait);
        return scmPurchaseUtils.updateSummaryOrder(update);
    }

    /**
     * 查询采购单及详情
     * @param req
     * @return
     */
    @Override
    public PurchaseOrderDetailResp queryPurchaseOrderAndDetail(OrderDetailReq req) {
        QueryWrapper<PurchaseOrder> query = new QueryWrapper<>();
        query.lambda()
                .eq(PurchaseOrder::getPmId,req.getPmId())
                .eq(PurchaseOrder::getPurchaseSn,req.getPurchaseSn());
        PurchaseOrder order = purchaseOrderService.getOne(query);
        if(order == null){
            throw new EmptyDataException("采购单为空");
        }
        PurchaseOrderDetailResp resp = new PurchaseOrderDetailResp();
        BeanUtil.copyProperties(order,resp);
        QueryWrapper<PurchaseOrderDetail> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(PurchaseOrderDetail::getPmId,req.getPmId())
                .eq(PurchaseOrderDetail::getPurchaseSn,req.getPurchaseSn());
        List<PurchaseOrderDetail> list = purchaseOrderDetailService.list(wrapper);
        List<PurchaseDetailCheckResp> res = new ArrayList<>();
        for(PurchaseOrderDetail detail : list){
            PurchaseDetailCheckResp check = new PurchaseDetailCheckResp();
            BeanUtil.copyProperties(detail,check);
            res.add(check);
        }
        resp.setDetailList(res);
        return resp;
    }

    /**
     * 查询所有采购任务（联查采购单明细）
     * @param req
     * @return
     */
    @Override
    public Page<PurchaseTaskListByDirectorResp> fetchTaskList(PurchasePageReq req) {
        String pmId = req.getPmId();
        Page page = new Page(req.getCurrent(), req.getSize());
        PurchaseTask purchaseTask = new PurchaseTask();
        BeanUtil.copyProperties(req,purchaseTask);
        IPage iPage = purchaseTaskService.page(page, Wrappers.query(purchaseTask).orderByDesc("create_date"));
        //根据任务列表查询商品信息
        List<PurchaseTask> taskList = (List<PurchaseTask>)iPage.getRecords();
        List<PurchaseTaskListResp> list = new ArrayList<>();
        for (PurchaseTask task : taskList) {
            if (StrUtil.isEmpty(task.getPurchaseDetailSn())){
                PurchaseTaskListResp resp = new PurchaseTaskListResp();
                // 审核任务 设置采购单状态
                QueryWrapper<PurchaseOrder> query = new QueryWrapper<>();
                query.lambda()
                        .eq(PurchaseOrder::getPmId, pmId)
                        .eq(PurchaseOrder::getPurchaseSn, task.getPurchaseSn());
                PurchaseOrder order = purchaseOrderService.getOne(query);
                if(null != order){
                    resp.setPurchaseStatus(order.getPurchaseStatus());
                }
                resp.setId(task.getId());
                resp.setPmId(task.getPmId());
                resp.setPurchaseSn(task.getPurchaseSn());
                resp.setDeadlineTime(task.getDeadlineTime());
                resp.setTaskStatus(task.getTaskStatus());
                resp.setTaskActionType(task.getTaskActionType());
                resp.setTransactorId(task.getTransactorId());
                resp.setTransactorName(task.getTransactorName());
                list.add(resp);
            }else {
                PurchaseOrderDetail orderDetail = new PurchaseOrderDetail();
                orderDetail.setPmId(pmId);
                orderDetail.setPurchaseDetailSn(task.getPurchaseDetailSn());
                PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(Wrappers.query(orderDetail));
                if(!ObjectUtil.isNull(detail)){
                    PurchaseTaskListResp resp = PurchaseTaskListTrans.getPurchaseTaskListReq(task, detail);
                    list.add(resp);
                }
            }
        }
        //设置返回参数
        page.setRecords(list);
        return page;
    }

    /**
     * 确认揽货
     * @param req
     * @return
     */
    @Override
    public Boolean deliveryTask(CompleteTaskReq req) {
        PurchaseOrderDetail query = new PurchaseOrderDetail();
        BeanUtil.copyProperties(req,query);
        PurchaseOrderDetail one = purchaseOrderDetailService.getOne(Wrappers.query(query));
        if(ObjectUtil.isNull(one)){
            throw new EmptyDataException();
        }
        PurchaseOrderDetail upd = new PurchaseOrderDetail();
        upd.setId(one.getId());
        upd.setPurchaseStatus(req.getPurchaseStatus());
        PurchaseOrderDetail queryList = new PurchaseOrderDetail();
        queryList.setPmId(req.getPmId());
        queryList.setPurchaseSn(one.getPurchaseSn());
        List<PurchaseOrderDetail> list = purchaseOrderDetailService.list(Wrappers.query(queryList));
        Boolean flag = true;
        if(!list.isEmpty()){
            for(PurchaseOrderDetail detail : list){
                if(detail.getPurchaseStatus() != req.getPurchaseStatus()){
                    flag=false;
                }
            }
        }
        if(flag){
            PurchaseOrder queryReq = new PurchaseOrder();
            queryReq.setPmId(req.getPmId());
            queryReq.setPurchaseSn(one.getPurchaseSn());
            PurchaseOrder updReq = new PurchaseOrder();
            updReq.setPurchaseStatus(req.getPurchaseStatus());
            if(!purchaseOrderService.update(updReq, Wrappers.query(queryReq))){
                throw new ErrorDataException();
            }
        }
        return purchaseOrderDetailService.updateById(upd);
    }


    /**
     * 总监 执行采购任务(审核) 批量通过
     *
     * @param req 采购任务id、执行人id、执行人备注、任务执行方式为审核
     * @return
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    @ApiOperation(value = "采购任务审核——B端" ,notes = "总监 执行采购任务(审核) 批量通过")
    public Boolean checkTaskBatch(CheckTaskBatchReq req) {
        //查询采购任务
        QueryWrapper<PurchaseTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(PurchaseTask::getPmId, req.getPmId())
                .eq(PurchaseTask::getTaskActionType, TaskActionTypeEnum.audit)
                .eq(PurchaseTask::getPurchaseSn, req.getPurchaseSn())
                .eq(PurchaseTask::getTaskStatus, TaskStatusEnum.wait);
        PurchaseTask auditTask = purchaseTaskService.getOne(queryWrapper);
        if (null == auditTask) {
            throw new ErrorDataException("无可审核的采购任务");
        }
        //修改任务状态为已完成
        PurchaseTask updateTask = new PurchaseTask();
        updateTask.setId(auditTask.getId());
        updateTask.setTaskStatus(TaskStatusEnum.finish);
        updateTask.setActionDesc(req.getActionDesc());
        updateTask.setActionTime(LocalDateTime.now());
        purchaseTaskService.updateById(updateTask);
        // 查询采购单
        PurchaseOrder purchaseOrder = new PurchaseOrder();
        purchaseOrder.setPmId(req.getPmId());
        purchaseOrder.setPurchaseSn(req.getPurchaseSn());
        PurchaseOrder one = purchaseOrderService.getOne(Wrappers.query(purchaseOrder));
        if (null == one) {
            throw new EmptyDataException("采购单查询有误");
        }
        if (req.getPurchaseStatus() == PurchaseStatusEnum.close) {
            //审核不通过
            return auditFailure(one, req);
        } else {
            //审核通过
            return checkPass(one, req);
        }
    }

    /**
     * 总监审核不通过
     * @param one
     * @param req
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    public Boolean auditFailure(PurchaseOrder one,CheckTaskBatchReq req){
        //修改采购单的采购状态
        PurchaseOrder updateOrder = new PurchaseOrder();
        updateOrder.setId(one.getId());
        updateOrder.setPurchaseStatus(req.getPurchaseStatus());
        purchaseOrderService.updateById(updateOrder);
        for (DetailReq detailReq : req.getDetailList()) {
            //查询采购单明细
            PurchaseOrderDetail orderDetail = new PurchaseOrderDetail();
            orderDetail.setPurchaseDetailSn(detailReq.getPurchaseDetailSn());
            orderDetail.setPmId(req.getPmId());
            PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(Wrappers.query(orderDetail));
            //修改采购单明细的采购状态
            PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
            purchaseOrderDetail.setId(detail.getId());
            purchaseOrderDetail.setPurchaseStatus(PurchaseStatusEnum.close);
            purchaseOrderService.updateById(updateOrder);
        }
        return true;
    }
    /**
     * 总监审核通过
     * @param one
     * @param req
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    public Boolean checkPass(PurchaseOrder one,CheckTaskBatchReq req){
        LocalDateTime finalTime = req.getBuyFinalTime();
        finalTime = (null == finalTime) ? one.getBuyFinalTime() : finalTime;
        //修改采购单的采购状态
        PurchaseOrder updateOrder = new PurchaseOrder();
        updateOrder.setId(one.getId());
        updateOrder.setPurchaseStatus(req.getPurchaseStatus());
        updateOrder.setBuyFinalTime(finalTime);
        purchaseOrderService.updateById(updateOrder);
        for (DetailReq detailReq : req.getDetailList()) {
            //查询采购单明细
            PurchaseOrderDetail orderDetail = new PurchaseOrderDetail();
            orderDetail.setPurchaseDetailSn(detailReq.getPurchaseDetailSn());
            orderDetail.setPmId(req.getPmId());
            PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(Wrappers.query(orderDetail));
            //修改商品数量
            PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
            purchaseOrderDetail.setNeedBuyNum(detailReq.getNeedBuyNum());
            purchaseOrderDetail.setId(detail.getId());
            purchaseOrderDetail.setPurchaseStatus(detailReq.getPurchaseStatus());
            // 设置采购截止时间
            LocalDateTime detailFinalTime = detailReq.getBuyFinalTime();
            detailFinalTime = (null == detailFinalTime) ? finalTime : detailFinalTime;
            purchaseOrderDetail.setBuyFinalTime(detailFinalTime);
            purchaseOrderDetailService.updateById(purchaseOrderDetail);
            // 单个明细取消
            if(detailReq.getPurchaseStatus() == PurchaseStatusEnum.close){
                continue;
            }
            // 创建分配任务
            PurchaseTask newTask = new PurchaseTask();
            newTask.setPmId(req.getPmId());
            newTask.setTaskStatus(TaskStatusEnum.wait);
            newTask.setTaskActionType(TaskActionTypeEnum.allocation);
            newTask.setTransactorId(detailReq.getTransactorId());
            newTask.setTransactorName(detailReq.getTransactorName());
            newTask.setContent(detailReq.getContent());
            newTask.setPurchaseDetailSn(detail.getPurchaseDetailSn());
            newTask.setPurchaseSn(req.getPurchaseSn());
            newTask.setDeadlineTime(detailFinalTime);
            //保存分配后的采购任务
            if (!purchaseTaskService.save(newTask)) {
                throw new ErrorDataException();
            }
        }
        return true;
    }
}
